<template>
  <div class="min-h-screen bg-gray-50 py-8">
    <div class="max-w-4xl mx-auto px-4">
      <!-- 页面标题 -->
      <div class="text-center mb-8">
        <h1 class="text-3xl font-bold text-gray-800 mb-2">错误异步 Provide 演示</h1>
        <p class="text-gray-600">展示在 setup 外部异步调用 provide 的错误用法</p>
        <router-link to="/" class="inline-block mt-4 text-vue-green hover:underline">← 返回首页</router-link>
      </div>

      <!-- 错误说明卡片 -->
      <div class="bg-red-50 border border-red-200 rounded-lg p-4 mb-6">
        <h3 class="font-semibold text-red-800 mb-2">❌ 错误行为</h3>
        <p class="text-red-700 mb-3">
          点击"异步加载数据"按钮后，即使在异步回调中调用了 provide()，
          子组件也不会收到更新。这是因为 provide 只能在组件 setup() 执行时建立依赖关系。
        </p>
        <div class="bg-red-100 p-3 rounded text-sm">
          <strong>正确解决方案：</strong> 应该在 setup 中使用 ref 或 reactive 创建响应式数据，
          然后在异步操作中修改这些响应式数据的值，而不是重新调用 provide。
        </div>
      </div>

      <!-- 父组件区域 -->
      <div class="bg-white rounded-lg shadow-md p-6 mb-6">
        <h2 class="text-xl font-semibold text-gray-800 mb-4">👨‍💼 父组件</h2>
        <div class="space-y-4">
          <p class="text-gray-600">
            当前用户对象：
            <span class="font-semibold text-vue-green">
              {{ currentUser ? JSON.stringify(currentUser) : 'null' }}
            </span>
          </p>
          <button 
            @click="loadData"
            :disabled="isLoading"
            class="bg-vue-green text-white px-6 py-2 rounded-lg hover:bg-vue-green-dark transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
          >
            {{ isLoading ? '异步加载中...' : '异步加载数据' }}
          </button>
        </div>
      </div>

      <!-- 子组件区域 -->
      <AsyncChild />

      <!-- 控制台日志 -->
      <div class="bg-gray-900 text-green-400 rounded-lg p-4 mt-6">
        <h3 class="font-semibold mb-2">📝 控制台日志</h3>
        <div class="font-mono text-sm space-y-1">
          <div v-for="(log, index) in logs" :key="index" class="opacity-80">
            {{ log }}
          </div>
        </div>
      </div>

      <!-- 正确解决方案示例 -->
      <div class="bg-blue-50 border border-blue-200 rounded-lg p-4 mt-6">
        <h3 class="font-semibold text-blue-800 mb-2">💡 正确的解决方案</h3>
        <div class="text-blue-700 text-sm space-y-2">
          <p><strong>错误写法：</strong></p>
          <pre class="bg-blue-100 p-2 rounded text-xs overflow-x-auto"><code>// ❌ 错误：在异步回调中调用 provide
setTimeout(() => {
  user = { name: '异步用户' }
  provide('user', user) // 无效！
}, 2000)</code></pre>
          
          <p><strong>正确写法：</strong></p>
          <pre class="bg-blue-100 p-2 rounded text-xs overflow-x-auto"><code>// ✅ 正确：使用响应式数据
const user = ref(null)
provide('user', user)

setTimeout(() => {
  user.value = { name: '异步用户' } // 有效！
}, 2000)</code></pre>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { provide, ref } from 'vue'
import AsyncChild from '@/components/AsyncChild.vue'

// 普通变量（非响应式）
let currentUser: { name: string } | null = null
const isLoading = ref(false)

// 日志记录
const logs = ref<string[]>([
  '[初始化] 父组件创建，user = null',
  '[provide] 向子组件提供普通变量 user (初始值为 null)'
])

// 向子组件提供普通变量
provide('user', currentUser)

function loadData() {
  isLoading.value = true
  logs.value.push(`[${new Date().toLocaleTimeString()}] 开始异步加载数据`)
  console.log('开始异步加载数据')
  
  setTimeout(() => {
    currentUser = { name: '异步用户' }
    
    // ❌ 错误：在 setup 外部、异步中调用 provide 无效
    try {
      provide('user', currentUser)
      logs.value.push(`[${new Date().toLocaleTimeString()}] ❌ 尝试在异步中重新 provide user`)
      logs.value.push('[错误] 异步中的 provide 调用无效，Vue 不会重新建立依赖注入')
    } catch (error) {
      logs.value.push(`[${new Date().toLocaleTimeString()}] ❌ provide 调用失败: ${error}`)
    }
    
    isLoading.value = false
    console.log('异步 provide 完成，但子组件不会更新')
  }, 2000)
}
</script>

<style scoped>
.text-vue-green {
  color: #42b883;
}

.bg-vue-green {
  background-color: #42b883;
}

.bg-vue-green-dark {
  background-color: #369870;
}

.hover\:bg-vue-green-dark:hover {
  background-color: #369870;
}
</style>